﻿using System;
using System.IO;

namespace IndirectX.Shaders
{
    public class InputRegisterDeclarationToken : InstrucitonCodeToken
    {
        public override void Parse(uint data)
        {
            base.Parse(data);

            // parse operand
        }
    }

    public class GlobalFlagsDeclarationToken : InstrucitonCodeToken
    {
        [Flags]
        public enum GlobalFlags
        {
            RefactoringAllowed = 1,
            EnableDoublePrecisionFloatOps = 2,
            ForceEarlyDepthStencilTest = 4,
            EnableRawAndStructuredBuffers = 8,
            SkipOptimizationsOfShaderIl = 16,
        }
        public GlobalFlags Flags;
        public override void Parse(uint data)
        {
            base.Parse(data);

            Flags = (GlobalFlags) BitExtensions.DecodeValue(data, 11, 18);
        }
    }
    public class ShaderChunk : Chunk
    {
        public override void Parse(DataStream stream)
        {
            BinaryReader reader = new BinaryReader(stream);
            var versionToken = ReadToken<VersionCodeToken>(reader);
            var length = reader.ReadUInt32();

            while (true)
            {
                var data = reader.ReadUInt32();

                var opCode = (OpCode)BitExtensions.DecodeValue(data, 0, 10);

                InstrucitonCodeToken token;
                switch (opCode){
                    case OpCode.dcl_global_flags:
                        token = new GlobalFlagsDeclarationToken();
                        break;
                    case OpCode.dcl_input:
                        token = new InputRegisterDeclarationToken();
                        break;
                    default:
                        throw new NotImplementedException("OpCode " + opCode + " not implemented");
                }

                token.Parse(data);

            }
        }


        private static T ReadToken<T>(BinaryReader reader) where T : ShaderCodeToken, new()
        {
            var token = new T();
            token.Parse(reader.ReadUInt32());

            return token;
        }
    }
}